home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Magnum One
/
Magnum One (Mid-American Digital) (Disc Manufacturing).iso
/
d12
/
asm_msc1.arc
/
EX57.ASM
< prev
next >
Wrap
Assembly Source File
|
1988-11-20
|
4KB
|
111 lines
TITLE Add Entry to an Ordered List (EX57.ASM)
PAGE ,132
DATA SEGMENT PARA 'DATA'
START_ADDR DW ?
DATA ENDS
OUR_CODE SEGMENT PARA 'CODE'
PUBLIC ADD_TO_OL
ADD_TO_OL PROC FAR
ASSUME CS:OUR_CODE,DS:DATA
PUSH DS ;Save caller's registers
PUSH CX
PUSH SI
PUSH BX
MOV BX,SEG DATA ;Initialize DS
MOV DS,BX
CALL B_SEARCH ;Is the value in the list?
JNC GOODBYE ; If so, exit
MOV BX,SI ; If not, copy compare addr. to Bx
MOV CX,ES:[DI] ;Find address of last element
SHL CX,1
ADD CX,DI ; and put it in CX
PUSH CX ;Save this address on the stack
SUB CX,SI ;Calculate no. of words to be moved
SHR CX,1
CMP AX,ES:[SI] ;Should compare el. be moved,too?
JA EXCLUDE
INC CX ; Yes. Increase move count by 1
JNZ CHECK_CNT
EXCLUDE: ADD BX,2 ; No. Adjust insert pointer
CHECK_CNT: CMP CX,0 ;Move count = 0?
JNE MOVE_ELS
POP SI ; If so, store value at end of list
MOV ES:[SI+2],AX
JMP SHORT INC_CNT ; then go increase element count
MOVE_ELS: POP SI ;Load start address for move
PUSH BX ;Save insert address on stack
MOVE_ONE: MOV BX,ES:[SI] ;Move one element down in list
MOV ES:[SI+2],BX
SUB SI,2 ;Point to next element
LOOP MOVE_ONE ;Repeat until all are moved
POP BX ;Retrieve insert address
MOV ES:[BX],AX ;Insert AX in the list
INC_CNT: INC WORD PTR ES:[DI] ;Add 1 to element count
GOODBYE: POP BX ;Restore registers
POP SI
POP CX
POP DS
RET ; and exit
ADD_TO_OL ENDP
;
; This is the B_SEARCH procedure from Example 5-6.
;
B_SEARCH PROC
CMP AX,ES:[DI+2] ;Search value < or = first el.?
JA CHK_LAST ; No. Go check last element
LEA SI,ES:[DI+2] ; Yes. Fetch addr. of first el.
JE EXIT_1ST ;If value = 1st element, exit
STC ;If value < 1st element, set CF
EXIT_1ST: RET
CHK_LAST: MOV SI,ES:[DI] ;Point to last element
SHL SI,1
ADD SI,DI
CMP AX,ES:[SI] ;Search value > or = last el.?
JB SEARCH ; No. Go search list
JE EXIT_LAST ; Yes. Exit if value = last el.
STC ;If value > last element, set CF
EXIT_LAST: RET ; and then exit
;
; Search for value within the list.
;
SEARCH: MOV START_ADDR,DI ;Save starting address in memory
MOV SI,ES:[DI] ;Fetch index
EVEN_IDX: TEST SI,1 ;Force index to an even value
JZ ADD_IDX
INC SI
ADD_IDX: ADD DI,SI ;Calculate next search address
COMPARE: CMP AX,ES:[DI] ;Search value found?
JE ALL_DONE ; If so, exit
JA HIGHER ; Otherwise, find correct half
;
; These instructions are executed if the search value is lower
; in the list.
;
CMP SI,2 ;Index = 2?
JNE IDX_OK
NO_MATCH: STC ; If so, set CF
JE ALL_DONE ; and exit
IDX_OK: SHR SI,1 ; If not, divide index by 2
TEST SI,1 ;Force index to an even value
JZ SUB_IDX
INC SI
SUB_IDX: SUB DI,SI ;Calculate next address
JMP SHORT COMPARE ;Go check this element
;
; These instructions are executed if the search value is higher
; in the list.
;
HIGHER: CMP SI,2 ;Index = 2?
JE NO_MATCH ; If so, go set CF and exit
SHR SI,1 ; If not, divide index by 2
JMP SHORT EVEN_IDX ;Go check next element
;
; Following are exit instructions.
;
ALL_DONE: MOV SI,DI ;Move compare address into SI
MOV DI,START_ADDR ;Restore starting address
RET ; and exit
B_SEARCH ENDP
OUR_CODE ENDS
END ADD_TO_OL